const tools = require("./pub/tools");
const Hook = require("./baseHook");
class GloabClass{
    constructor(){
        this._data = {
            userAudioOpen : true,
            userEffectOpen :  true
        }
    }

    append( opts ){
        opts = opts || {};
        for(let key in opts){
            if( tools.isType( this._data[key] , "Undefined") ){
                this._data[key] = opts[key] //tools.clone( opts[key] )
            }
        }
    }

    getRef( key ){
        let keys = tools.transArr( key , ".");
        let ref = this._data;
        ref = (ref[keys[0]] && ref[keys[0]].getRef ) ? ref[keys[0]].getRef( ...Array.prototype.slice.call(keys , 1) ) : null;

        return ref;
    }

    get( key ){
        let args = Array.prototype.slice.call(arguments);
        if(this._data[key] && this._data[key].get){
            return this._data[key].get.apply( this._data[key] , Array.prototype.slice.call(args ,1)  );
        }else
            return this._data[key]
    }

    set(key , v ){
        let re = null;
        let args = Array.prototype.slice.call(arguments);
        if(this._data[key] && this._data[key].set){
            re = this._data[key].set.apply( this._data[key] , Array.prototype.slice.call(args ,1) );
            // this._runKeyHandlers( this._hookName(key , "set") , [re] );
            return re
        }else
            this._data[key] = v;
            // this._runKeyHandlers( this._hookName(key) , [v] );
            return v;
    }

    do( key , meth ){
        let keys = tools.transArr( key , ".") , re = null;
        let args = Array.prototype.slice.call(arguments) , 
            params = Array.prototype.slice.call(args ,2);
        if( keys.length == 1){
            if(this._data[key] && this._data[key][meth] && tools.isType(this._data[key][meth] , "Function") ){
                re = this._data[key][meth].apply( this._data[key] , params );
                // let args = [re].concat( params );
                // this._runKeyHandlers( this._hookName(key,meth) , args );
                return re;
            }
        }else if(keys.length>1){
            params = Array.prototype.slice.call(args ,1)
            let tmp = this._data , last= tmp;
            let i=0;
            while( tmp && i<keys.length){
                last = tmp;
                tmp = tmp._data ? tmp._data[keys[i]] : tmp[keys[i]] ;
                i++
            }
            re = tmp && tools.isType(tmp , "Function") ? tmp.apply( last , params ) : null;
            // let tmparr = [re].concat( params );
            // this._runKeyHandlers( this._hookName(keys) , tmparr );
            return re;
        }
        return re;
    }

    _hookName( key , meth ){
        let re = key;
        re = meth ? key + "." + meth : key;
        return re;
    }

//用于事件监听与分发
    _runKeyHandlers( keys , args ){
        if(!this.__hook) return;
        args = args || [];
        args = tools.isType(args , "Array") ? args : [args];
        console.log("rankeyHandler:" +  keys );

        this.__hook.run( keys , ...args );
    }

    //当某个状态变化为指定值时执行的逻辑钩子
    //value ：当变化为某个值时触发
    whenKeyRun( keys , handlerp , value){
        this.__hook = this.__hook || new Hook();

        // if(!T.isType(value , "Undefined")){
        //     handlerp.checkrun = ()=>{ return this.getAttr(attr)===value };
        // }

        this.__hook.append( keys , handlerp );
    }

    whenKeyRunOnce( keys ,  handler , value ){
        let params = {
            once : true , 
            handler : handler
        }
        this.whenKeyRun( keys , params , value );
    }

    whenKeyChange( keys , handler , args ){
        this.__hook = this.__hook || new Hook();
        
        args = args || [];
        let handlerp = {
            handler : ( last , cur )=>{
                if( last !== cur){
                    let neargus = [last , cur];
                    neargus = Array.prototype.concat.call( [] , neargus, args );
                    handler( ...neargus );
                } 
            }
        }
        args && ( handlerp.params = args )
        this.__hook.append( keys , handlerp );
    }

    whenKeyChangeOnce( keys , handler , args ){
        this.__hook = this.__hook || new Hook();
        
        args = args || [];
        let handlerp = {
            once : true , 
            handler : ( last , cur )=>{
                if( last !== cur){
                    let neargus = [last , cur];
                    neargus = Array.prototype.concat.call( [] , args , neargus);
                    handler( ...neargus );
                }
            }
        }
        args && ( handlerp.params = args )
        this.__hook.append( keys , handlerp );
    }
}
module.exports = GloabClass;